﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace WinServerLibrary
{
    public delegate void StatusChangedEventHandler(object sender, StatusChangedEventArgs e);
    public class WinServer
    {
        public static Hashtable htUsers = new Hashtable(30);
        public static Hashtable htConnections = new Hashtable(30);
        private IPAddress ipAddress;
        private TcpClient tcpClient;
        public static event StatusChangedEventHandler StatusChanged;
        private static StatusChangedEventArgs e;

        public WinServer(IPAddress address)
        {
            ipAddress = address;
        }

        private Thread thrListener;
        private TcpListener tlsClient;
        bool ServRunning = false;

        public static void AddUser(TcpClient tcpUser, string strUsername)
        {
            WinServer.htUsers.Add(strUsername, tcpUser);
            WinServer.htConnections.Add(tcpUser, strUsername);

            SendAdminMessage(htConnections[tcpUser] + " has joined us");
        }

        public static void RemoveUser(TcpClient tcpUser)
        {
            if (htConnections[tcpUser] != null)
            {
                SendAdminMessage(htConnections[tcpUser] + " has left us");

                WinServer.htUsers.Remove(WinServer.htConnections[tcpUser]);
                WinServer.htConnections.Remove(tcpUser);
            }
        }

        public static void OnStatusChanged(StatusChangedEventArgs e)
        {
            StatusChangedEventHandler statusHandler = StatusChanged;
            if (statusHandler != null)
            {
                statusHandler(null, e);
            }
        }

        private static void SendAdminMessage(string p)
        {
            StreamWriter swSenderSender;

            e = new StatusChangedEventArgs("Administrator: " + p);
            OnStatusChanged(e);

            TcpClient[] tcpClients = new TcpClient[WinServer.htUsers.Count];
            WinServer.htUsers.Values.CopyTo(tcpClients, 0);

            for (int i = 0; i < tcpClients.Length; i++)
            {
                try
                {
                    if (p.Trim() == "" || tcpClients[i] == null)
                    {
                        continue;
                    }
                    swSenderSender = new StreamWriter(tcpClients[i].GetStream());
                    swSenderSender.WriteLine("Administrator: " + p);
                    swSenderSender.Flush();
                    swSenderSender = null;
                }
                catch
                {
                    RemoveUser(tcpClients[i]);
                }
            }
        }

        public static void SendMessage(string From, string Message)
        {
            StreamWriter swSenderSender;

            e = new StatusChangedEventArgs(From + " says: " + Message);
            OnStatusChanged(e);

            TcpClient[] tcpClients = new TcpClient[WinServer.htUsers.Count];
            WinServer.htUsers.Values.CopyTo(tcpClients, 0);

            for (int i = 0; i < tcpClients.Length; i++)
            {
                try
                {
                    if (Message.Trim() == "" || tcpClients[i] == null)
                    {
                        continue;
                    }

                    swSenderSender = new StreamWriter(tcpClients[i].GetStream());
                    swSenderSender.WriteLine(From + " says: " + Message);
                    swSenderSender.Flush();
                    swSenderSender = null;
                }
                catch
                {
                    RemoveUser(tcpClients[i]);
                }
            }
        }

        public void StartListening()
        {
            IPAddress ipaLocal = ipAddress;
            tlsClient = new TcpListener(1986);
            tlsClient.Start();
            ServRunning = true;
            thrListener = new Thread(KeepListening);
            thrListener.Start();
        }

        private void KeepListening()
        {
            while (ServRunning == true)
            {
                tcpClient = tlsClient.AcceptTcpClient();
                Connection newConnection = new Connection(tcpClient);
            }
        }
    }
}
